from django import forms
from django.contrib.auth import authenticate
from markdown import markdown
from lxml import etree

from .models import UserInfo, Cover, Tags


# 登录时使用的from
class LoginForm(forms.Form):
    username = forms.CharField(error_messages={'required': '请输入用户名'})
    password1 = forms.CharField(error_messages={'required': '请输入密码'})


# 注册时使用的from，继承值登录时的表单
class RegisterForm(LoginForm):
    mail = forms.EmailField(error_messages={'required': '请输入邮箱号'})
    password2 = forms.CharField(error_messages={'required': '请再输入密码'})
    code = forms.CharField(error_messages={'required': '请输入验证码'})

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)

    # 验证码钩子
    def clean_code(self):
        code_user = self.cleaned_data.get('code')  # 用户输入的验证码
        code = self.request.session.get('code')  # 会话中的验证码
        if not code:
            self.add_error('code', '验证码已失效，请重新获取！')
            return self.cleaned_data
        elif code_user != code:
            self.add_error('code', '验证码输入错误')
            return self.cleaned_data
        return code_user

    # 用户名钩子
    def clean_username(self):
        username = self.cleaned_data.get('username')  # 获取用户输入的用户名
        username_exists = UserInfo.objects.filter(username=username).exists()  # 根据输入的名字查找数据库中是否有该名字
        if username_exists:
            self.add_error('username', '用户名不能重复')
            return self.cleaned_data
        return username


# 添加文章时使用的表单
class ArticleForm(forms.Form):
    title = forms.CharField(error_messages={'required': '请输入标题'})
    content = forms.CharField(error_messages={'required': '请输入内容'})
    abstract = forms.CharField(required=False)  # 摘要
    cover = forms.IntegerField()  # 封面id
    tag = forms.JSONField(required=False)  # 标签
    category = forms.IntegerField(required=False)  # 分类
    status_choice = (
        (0, '未发布'),
        (1, '已发布'),
    )
    status = forms.ChoiceField(choices=status_choice)  # 状态

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super().__init__(*args, **kwargs)

    # 封面
    def clean_cover(self):
        cover = self.cleaned_data['cover']
        if cover == -1:
            if self.request.session.get('img_id'):
                img_id = self.request.session.pop('img_id')
                cover = img_id
            else:
                self.add_error('cover', '请选择封面')
                return self
        return cover

    # 摘要
    def clean_abstract(self):
        abstract = self.cleaned_data.get('abstract')
        if not abstract:
            html_content = markdown(self.cleaned_data['content'])  # 将markdown文本解析为html文本
            html = etree.HTML(html_content)  # 通过xpath获取里面的所有内容
            html_content_str = "".join(html.xpath('//*/text()')).replace('\n', '').replace('\t', '').replace(' ', '')
            abstract = html_content_str[0:256]
        return abstract

    # 标签钩子
    def clean_tag(self):
        tag = self.cleaned_data.get('tag')
        if tag:
            for i in range(len(tag)):
                # 如果输入的是十进制的话，则说明数据库中存在
                if not tag[i].isdecimal():
                    # 判断输入的值标签表中是否存在
                    if Tags.objects.filter(title=tag[i].upper()).exists():
                        # 如果存在，则设置
                        tag_obj = Tags.objects.filter(title=tag[i])
                        tag[i] = str(tag_obj.nid)
                    else:
                        # 否则添加
                        tag_obj = Tags.objects.create(title=tag[i])
                        tag[i] = str(tag_obj.nid)
        return tag


# 修改密码时使用的表单验证
class EditpasswordForm(forms.Form):
    nid = forms.CharField(error_messages={'required': '参数不正确'})
    password = forms.CharField(error_messages={'required': '请输入原密码'})
    newPassword1 = forms.CharField(error_messages={'required': '请输入新密码'})
    newPassword2 = forms.CharField(error_messages={'required': '请再次输入新密码'})

    # 验证原密码
    def clean_password(self):
        password = self.cleaned_data.get('password')
        if password:
            # 验证旧密码
            userinfo = UserInfo.objects.filter(nid=self.cleaned_data.get('nid')).first()
            user = authenticate(username=userinfo.username, password=password)
            # 如果验证错误
            if not user:
                self.add_error('password', '原密码输入错误')
            return password

    # 验证新密码
    def clean_newPassword2(self):
        newpassword1 = self.cleaned_data.get('newPassword1')
        newpassword2 = self.cleaned_data.get('newPassword2')
        if newpassword1 != newpassword2:
            self.add_error('newPassword2', '新密码输入错误')


# 意见反馈时使用的表单验证
class FeedbackForm(forms.Form):
    email = forms.EmailField(error_messages={'required': '请输入邮箱号'})
    content = forms.CharField(error_messages={"required": '请输入反馈意见'})


# 发布评论时使用的表单验证
class CommentForm(forms.Form):
    nid = forms.IntegerField()
    content = forms.CharField(error_messages={'required': '评论内容不能为空！'})
    user = forms.IntegerField()
    rootComment = forms.IntegerField()
